//
//  Exception.hpp
//  Simulation
//
//  Created by Christopher Kemsley on 2/27/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef Simulation_Exception_hpp
#define Simulation_Exception_hpp

#include <string>
#include <vector>
#include <ostream>
#include <iostream>
#include <sstream>

#define	NamespaceBegin		namespace Sim {
#define	NamespaceEnd		}

NamespaceBegin



struct	Exception ;
struct	ExceptionTrace ;



#define		ThrowException(domain,stream,file,line)		{ std::stringstream str ; str << stream ; std::string strr = str.str() ; if(strr.size()==0)strr="No description"; throw Sim::Exception(domain,strr,file,line) ; }

#define		AddExceptionTrace(exception,domain,stream,file,line)	{ std::stringstream str ; str << stream ; exception.add(domain,str.str(),file,line) ; }




struct	Exception
{
	Exception	( std::string const & inDomain , std::string const & inDescription , char const * inFile , int inLine ) ;
	Exception	( Exception const & copy ) ;
	~Exception	() ;
	
	void	add	( std::string const & inDomain , std::string const & inDescription , char const * inFile , int inLine ) ;
	
	
	std::vector<ExceptionTrace> const&		trace () ;
	
private:
	std::vector<ExceptionTrace>		mTrace ;
	friend std::ostream&	operator<<	( std::ostream & stream , Exception const & exception ) ;
};







struct	ExceptionTrace
{
	ExceptionTrace	( std::string const & inDomain , std::string const & inDescription , char const * inFile , int inLine ) ;
	ExceptionTrace	( ExceptionTrace const & copy ) ;
	~ExceptionTrace	() ;
	
	std::string		domain ;
	std::string		description ;
	
	std::string		file ;
	int				line ;
	
	void	operator=	( ExceptionTrace const & copy ) ;
	
private:
	friend std::ostream&	operator<<	( std::ostream & stream , ExceptionTrace const & exception ) ;
} ;





NamespaceEnd

#endif
